package l1j.opqlo.Server.L1World;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import l1j.server.server.model.Instance.L1NpcInstance;
import l1j.server.server.model.map.L1Map;
import l1j.server.server.types.Point;


/**
 * 世界NPC暫存區<BR>
 *
 * @author dexc
 *
 */
public class WorldNpc {

	private static final Logger _log = Logger.getLogger(WorldNpc.class.getName());

	private static WorldNpc _instance;

	public static WorldNpc get() {
		if (_instance == null) {
			_instance = new WorldNpc();
		}
		return _instance;
	}

	private final ConcurrentHashMap<Integer, L1NpcInstance> _isMob;

	private Collection<L1NpcInstance> _allMobValues;

	private WorldNpc() {
		this._isMob = new ConcurrentHashMap<Integer, L1NpcInstance>();
	}

	/**
	 * 全部NPC
	 * @return
	 */
	public Collection<L1NpcInstance> all() {
		try {
			final Collection<L1NpcInstance> vs = this._allMobValues;
			return vs != null ? vs : (this._allMobValues = Collections.unmodifiableCollection(this._isMob.values()));
			//return Collections.unmodifiableCollection(_isCrown.values());

		} catch (final Exception e) {
			_log.log(Level.WARNING,e.getLocalizedMessage(), e);
		}
		return null;
	}

	/**
	 * 該地圖中的所有NPC(只傳回第一個符合條件的物件)
	 * @return L1NpcInstance npc
	*/

	public L1NpcInstance getNpcForMap(final int mapid , final int npcid){
		for (L1NpcInstance element : this.all()) {
			if(element.getMapId() == mapid
					&& element.getNpcId() == npcid){
				return element;
			}
		}
		return null;
	}

	/**
	 * 13格範圍內相同NPC物件數量
	 * @param src 原始物件
	 * @return
	 */
	public int getVisibleCount(final L1NpcInstance src) {
		final L1Map map = src.getMap();
		final Point pt = src.getLocation();
		int count = 0;

		for (L1NpcInstance element : this.all()) {
			//for (final L1NpcInstance element : this._isMob.values()) {
			if (element.equals(src)) {
				continue;
			}
			if (map != element.getMap()) {
				continue;
			}
			// 13格內NPC
			if (pt.isInScreen(element.getLocation())) {
				if (src.getNpcId() == element.getNpcId()) {
					count++;
				}
			}
		}

		return count;
	}

	/**
	 * 13格範圍NPC物件
	 * @param src 原始物件
	 * @return
	 */
	public ArrayList<L1NpcInstance> getVisibleMob(final L1NpcInstance src) {
		final L1Map map = src.getMap();
		final Point pt = src.getLocation();
		final ArrayList<L1NpcInstance> result = new ArrayList<L1NpcInstance>();

		for (L1NpcInstance element : this.all()) {
			//for (final L1NpcInstance element : this._isMob.values()) {
			if (element.equals(src)) {
				continue;
			}
			if (map != element.getMap()) {
				continue;
			}
			// 13格內NPC
			if (pt.isInScreen(element.getLocation())) {
				result.add(element);
			}
		}

		return result;
	}

	/**
	 * NPC清單
	 * @return
	 */
	public ConcurrentHashMap<Integer, L1NpcInstance> map() {
		return this._isMob;
	}

	/**
	 * 加入NPC清單
	 * @param key
	 * @param value
	 */
	public void put(final Integer key, final L1NpcInstance value) {
		try {
			this._isMob.put(key, value);

		} catch (final Exception e) {
			_log.log(Level.WARNING,e.getLocalizedMessage(), e);
		}
	}


	/**
	 * 移出NPC清單
	 * @param key
	 */
	public void remove(final Integer key) {
		try {
			this._isMob.remove(key);

		} catch (final Exception e) {
			_log.log(Level.WARNING,e.getLocalizedMessage(), e);
		}
	}



}
